package com.car.loan.framework.aspectj;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.car.loan.common.enums.LoanStatusEnum;
import com.car.loan.common.utils.ObjectStruct;
import com.car.loan.common.utils.ServletUtils;
import com.car.loan.common.utils.StringUtils;
import com.car.loan.common.utils.spring.SpringUtils;
import com.car.loan.framework.aspectj.lang.annotation.DataScope;
import com.car.loan.framework.aspectj.lang.annotation.DataStatus;
import com.car.loan.framework.security.LoginUser;
import com.car.loan.framework.web.domain.AjaxResult;
import com.car.loan.framework.web.domain.BaseEntity;
import com.car.loan.project.system.domain.SysUser;
import com.car.loan.project.xr.util.bo.business.LoanBaseInfo;
import com.car.loan.project.xr.util.select.LoanBasePageParam;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author huangding
 * @description 流程状态过滤
 * @date 2019/11/9 15:20
 */
@Aspect
@Component
@Slf4j
public class DataStatusAspect {

    /**
     * 类型的实现集合
     */
    private HashMap<LoanStatusEnum, DataStatusSqlService> dataStatusSqlServiceHashMap = new HashMap<>();

    @Autowired
    private DataStatusAspect(List<DataStatusSqlService> dataStatusSqlServices) {
        dataStatusSqlServices.forEach(dataStatusSqlService -> {
            dataStatusSqlServiceHashMap
                .put(dataStatusSqlService.getLoanStatusEnum(), dataStatusSqlService);
        });
    }


    @Pointcut("@annotation(com.car.loan.framework.aspectj.lang.annotation.DataStatus)")
    public void dataDataPointCut() {
    }

    @Around("dataDataPointCut()")
    public Object doBefore(ProceedingJoinPoint point) throws Throwable {
        return handleDataData(point);
    }


    private Object handleDataData(final ProceedingJoinPoint joinPoint) {
        // 获得注解
        DataStatus controllerDataStatus = getAnnotationLog(joinPoint);
        if (controllerDataStatus == null) {
            return AjaxResult.error("不存在DataStatus注解");
        }

        DataStatusSqlService dataStatusSqlService = dataStatusSqlServiceHashMap
            .get(controllerDataStatus.loanStatusEnum());
        if (null == dataStatusSqlService) {
            return AjaxResult.error("不存在DataStatus类型实现了类");
        }
        dataStatusFilter(joinPoint, controllerDataStatus.statusAlias(),
            dataStatusSqlService);
        AjaxResult ajaxResult;
        try {
            ajaxResult = (AjaxResult) joinPoint.proceed();
        } catch (Throwable throwable) {
            return AjaxResult.error(throwable.getMessage());
        }
        if (null != ajaxResult) {
            Object o = ajaxResult.get(AjaxResult.DATA_TAG);
            if (null != o) {
                Page<LoanBaseInfo> page = (Page<LoanBaseInfo>) o;
                List<LoanBaseInfo> records = page.getRecords();
                if (StringUtils.isNotEmpty(records)) {
                    List<LoanBaseInfo> collect = records.parallelStream()
                        .map(dataStatusSqlService::getStatusRemark)
                        .collect(Collectors.toList());
                    page.setRecords(collect);
                }
            }
            return ajaxResult;
        }
        return null;
    }

    /**
     * 是否存在注解，如果存在就获取
     */
    private DataStatus getAnnotationLog(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        if (method != null) {
            return method.getAnnotation(DataStatus.class);
        }
        return null;
    }

    /**
     * 业务状态过滤
     *
     * @param joinPoint 切点
     * @param statusAlias 业务状态表 别名
     */
    private void dataStatusFilter(ProceedingJoinPoint joinPoint, String statusAlias,
        DataStatusSqlService dataStatusSqlService) {
        //添加业务状态sql
        ObjectStruct objectStruct = new ObjectStruct(joinPoint.getArgs()[0]);
        Integer status = (Integer) objectStruct.getMethod("getStatus", null);
        objectStruct.getMethod("setDataStatus",
            new Object[]{
                " AND ( " + dataStatusSqlService.getSql(statusAlias, status) + " )"});
        objectStruct
            .getMethod("setSortDesc", new Object[]{dataStatusSqlService.getSortSql(statusAlias)});
    }

    private void handleData() {

    }


}
